'use strict'
const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}

const Timestamp = new Date().getTime()
const name = 'cmxBlog' // page title

// webpack启用Gzip压缩
const CompressionPlugin = require('compression-webpack-plugin')
const productionGzipExtensions = ['js', 'css']
const zlib = require('zlib')
const isPRD = process.env.NODE_ENV === 'production'

module.exports = {
  productionSourceMap: true,
  // 配置代理服务器, 用于解决跨域问题
  /*
  //  这种方式仅能配置一台代理服务器, 且当可以在public找到文件时优先拿去public下的文件作为请求内容返回
  devServer: {
    proxy: 'http://localhost:4000'
  },
  */
  outputDir: './dist', // build输出目录
  indexPath: './templates/index.html', // 打包后index的位置
  assetsDir: 'static/', // 静态资源目录（js, css, img）
  lintOnSave: false, // 是否开启eslint



  css: {
    extract: {
      filename: `static/css/[name].${Timestamp}.css`,
      chunkFilename: `static/css/[name].${Timestamp}.css`
    }
  },

  devServer: {
    // 通过设置不同的请求前缀来控制是否走代理服务器及配置多台代理服务器
    proxy: {
      '/api': {
        // target: 'https://com.cmx.ink', // 代理的目标的基础路径
        target: "http://127.0.0.1:5000",
        ws: true, // 是否开启WebSocket
        changeOrigin: true, // 设置为true时代理服务的host 值为 5000(与目标服务器端口号保持一致), 设置为 false host时值为8080(如果目标服务器设置了限制,可能会导致无法请求失败),
        pathRewrite: { '^/api': '' } // 必须配置, 用于解决请求替换到请求前缀(这里的请求前缀是'/api')
      },
      '/bpi': {
        // target: 'https://com.cmx.ink', // 代理的目标的基础路径
        target: "https://47.105.79.58",
        ws: true, // 是否开启WebSocket
        changeOrigin: true, // 设置为true时代理服务的host 值为 5000(与目标服务器端口号保持一致), 设置为 false host时值为8080(如果目标服务器设置了限制,可能会导致无法请求失败),
        pathRewrite: { '^/bpi': '' } ,// 必须配置, 用于解决请求替换到请求前缀(这里的请求前缀是'/api')

      }
    }
  },
  // 使用Gzip压缩文件
  configureWebpack: {
    name: name,
    output: {
      // 输出重构  打包编译后的 文件名称  【模块名称.版本号.时间戳】
      filename: `static/js/[name].${Timestamp}.js`,
      chunkFilename: `static/js/[name].${Timestamp}.js`,
    },
    plugins: isPRD
      ? [
        // 使用Gzip压缩文件 - https://segmentfault.com/a/1190000012571492
        // 报错："TypeError: Cannot read property 'tapPromise' of undefined"是compression-webpack-plugin版本问题5.0.1
        new CompressionPlugin({
          filename: '[path].gz[query]',
          algorithm: 'gzip',
          test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
          threshold: 10240,
          // minRatio: 0.8
          minRatio: 1,         // 强制生成压缩文件
          compressionOptions: { level: 9 } // 最大压缩
        }),
        new CompressionPlugin({
          filename: '[path].br[query]',
          algorithm: 'brotliCompress',
          test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
          threshold: 10240,
          minRatio: 1,
          compressionOptions: {
            params: {
              [zlib.constants.BROTLI_PARAM_QUALITY]: 11 // 最大压缩等级
            }
          }
        })
      ]
      : [],
    // provide the app's title in webpack's name field, so that
    // it can be accessed in index.html to inject the correct title.
    resolve: {
      alias: {
        '@': resolve('src')
      }
    },
    externals: {
      // CDN 的 Element 依赖全局变量 Vue， 所以 Vue 也需要使用 CDN 引入
      vue: 'Vue',
      'vue-router': 'VueRouter',
      // 属性名称 element-ui, 表示遇到 import xxx from 'element-ui' 这类引入 'element-ui'的，
      // 不去 node_modules 中找，而是去找 全局变量 ELEMENT
      'element-ui': 'ELEMENT',
      tinymce: 'tinymce'
    }
  },
  chainWebpack(config) {

    // config.plugin('html').tap(args => {
    //   // 设置favicon.ico在打包时的路径
    //   args[0].favicon = 'static/favicon.ico';
    //   return args;
    // });

    config.when(process.env.NODE_ENV === 'production', (config) => {
      // 修改输出文件名以包含hash，以避免缓存问题
      config.output
        .filename('[name].[contenthash:8].js')
        .chunkFilename('[name].[contenthash:8].chunk.js');
    });

    // it can improve the speed of the first screen, it is recommended to turn on preload
    // it can improve the speed of the first screen, it is recommended to turn on preload
    config.plugin('preload').tap(() => [
      {
        rel: 'preload',
        // to ignore runtime.js
        // https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
        fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/, /chunk-vendors\..*\.css$/],
        include: 'initial'
      }
    ])



    // when there are many pages, it will cause too many meaningless requests
    config.plugins.delete('prefetch')

    // set svg-sprite-loader
    config.module.rule('svg').exclude.add(resolve('src/icons')).end()
    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/icons'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]'
      })
      .end()

    config.when(process.env.NODE_ENV !== 'development', config => {
      // config
      //   .plugin('ScriptExtHtmlWebpackPlugin')
      //   .after('html')
      //   .use('script-ext-html-webpack-plugin', [{
      //     // `runtime` must same as runtimeChunk name. default is `runtime`
      //     inline: /runtime\..*\.js$/
      //   }])
      //   .end()
      config.optimization.splitChunks({
        chunks: 'all',
        cacheGroups: {
          libs: {
            name: 'chunk-libs',
            test: /[\\/]node_modules[\\/]/,
            priority: 10,
            chunks: 'initial' // only package third parties that are initially dependent
          },
          elementUI: {
            name: 'chunk-elementUI', // split elementUI into a single package
            priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
            test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
          },
          commons: {
            name: 'chunk-commons',
            test: resolve('src/components'), // can customize your rules
            minChunks: 3, //  minimum common number
            priority: 5,
            reuseExistingChunk: true
          }
        }
      })
      // https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
      config.optimization.runtimeChunk('single')
    })
  }
}
